import { PNode } from "~/models/graph/node/prototype"
import { PNodeType } from "~/models/graph/node/type"
import { PSlot } from "~/models/graph/slot/prototype"
import { PSlotType } from "~/models/graph/slot/type"
import { PyBundle } from "./PyBundle"
import { tAny, tBool, tNum, tStr } from "~/models/types"
import { PyVar } from "../pyCode/PyVar"
import { PyFunc, PyFuncSign } from "../pyCode/PyFunc"
import { ListType } from "../types/list_type"
import { _T } from "../types/type_template"

/**
 * 内置模组
 */
const bundle = new PyBundle('builtin', '基本功能')

bundle.addFunc(new PyFunc({
  sign: new PyFuncSign('调试输出', [
    { name: '消息', type: tAny },
  ]),
  implement: `\
def 调试输出(消息):
  global logs
  logs.append(消息)
`,
  dependencies: [new PyVar('logs', [])]
}))

bundle.addFunc(new PyFunc({
  isPure: true,
  sign: new PyFuncSign('拼接',
    [
      { name: 'A', type: tStr },
      { name: 'B', type: tStr },
    ],
    [
      { name: 'AB', type: tStr },
    ]
  ),
  implement: `\
def 拼接(a, b):
  return a + b
`
}))

bundle.addFunc(new PyFunc({
  isPure: true,
  sign: new PyFuncSign('范围',
    [
      { name: '开始', type: tNum },
      { name: '结束', type: tNum },
    ],
    [
      { name: 'list', type: new ListType(tNum) },
    ]
  ),
  implement: `\
def 范围(a, b):
  return list(range(a, b+1))
`
}))

bundle.addFunc(new PyFunc({
  typeTemplates: [_T],
  sign: new PyFuncSign('hh',
    [
      { name: 'a', type: _T },
      { name: 'b', type: _T },
    ],
    [
      { name: 'aplusb', type: _T },
    ]
  ),
  implement: `\
def hh(a, b):
  return a + b
`
}))


bundle.extraNode = [
  new PNode({
    type: PNodeType.Process,
    name: 'Condition',
    title: '分支',
    slots: [
      PSlot.Preset.ProcessIn,
      PSlot.Preset.ProcessOut,
      PSlot.InData('condition', '条件', tBool),
      new PSlot('_out_yes', '真', 'out', PSlotType.Process),
      new PSlot('_out_no', '假', 'out', PSlotType.Process),
    ],
    processTemplate: "if %(data[0])s:\n",
    branchTemplate: "%(process[0])s\n%(indent)selse:\n%(process[1])s\n",
  }),
  new PNode({
    type: PNodeType.Process,
    name: 'Iterate',
    title: '迭代',
    slots: [
      PSlot.Preset.ProcessIn,
      PSlot.Preset.ProcessOut,
      PSlot.InData('Iterateor', '列表', new ListType(_T)),
      new PSlot('_item', '子项', 'out', PSlotType.Data, _T),
      new PSlot('_out_inner', '过程', 'out', PSlotType.Process),
    ],
    processTemplate: "for %(returns[0])s in %(data[0])s:\n",
    branchTemplate: "%(process[0])s\n",
    typeTemplates: [ _T ]
  }),
  new PNode({
    type: PNodeType.Process,
    name: 'Loop',
    title: '循环',
    slots: [
      PSlot.Preset.ProcessIn,
      PSlot.Preset.ProcessOut,
      PSlot.InData('condition', '条件', tBool),
      new PSlot('_out_inner', '重复', 'out', PSlotType.Process),
    ],
    processTemplate: "while %(data[0])s:\n",
    branchTemplate: "%(process[0])s\n",
  }),
  new PNode({
    typeTemplates: [ _T ],
    type: PNodeType.Expression,
    name: 'Add',
    title: '+',
    slots: [
      PSlot.InData('A', '', _T),
      PSlot.InData('B', '', _T),
      PSlot.OutData('AplusB', '', _T),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'Minus',
    title: '-',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AminusB', '', tNum),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'Multiply',
    title: '*',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AmultiplyB', '', tNum),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'DivideBy',
    title: '/',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AdividebyB', '', tNum),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'RemainderBy',
    title: '%',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AremainderbyB', '', tNum),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'Equal',
    title: '==',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AeqB', '', tBool),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'GreatThan',
    title: '>',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AgtB', '', tBool),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'LessThan',
    title: '<',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AltB', '', tBool),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'GreatThanEqual',
    title: '>=',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AgteB', '', tBool),
    ]
  }),
  new PNode({
    type: PNodeType.Expression,
    name: 'LessThanEqual',
    title: '<=',
    slots: [
      PSlot.InData('A', '', tNum),
      PSlot.InData('B', '', tNum),
      PSlot.OutData('AlteB', '', tBool),
    ]
  }),
  new PNode({
    type: PNodeType.PureFunc,
    name: 'str',
    title: '转化为字符串',
    slots: [
      PSlot.InData('src', '', tAny),
      PSlot.OutData('dst', '', tStr),
    ]
  }),
]

export const bunBuiltin = bundle